<a name="Guice-IntegratingApacheShirointoGuicebasedApplication"></a>
Integrating Apache Shiro into Guice based Application
=====================================================

Shiro [Guice](https://github.com/google/guice) integration was added in Shiro 1.2\. This page covers the ways to integrate Shiro into Guice-based applications using standard Guice conventions and mechanisms. Prior to reading this integration document, you should be a least somewhat familiar with Guice.

<a name="Guice-Overview"></a>
Overview
--------

shiro-guice provides three Guice modules that can be included in your application.

*   ShiroModule
    *   Provides basic integration for setting up the `SecurityManager`, any `Realms`, and any other Shiro configuration.
    *   This module is used by extending it and adding your own custom configuration.

*   ShiroWebModule
    *   Extension of `ShiroModule` that sets up the web environment and also allows for filter chain configuration. This uses the [Guice Servlet Module](https://github.com/google/guice/wiki/ServletModule) to configure the filters, and so requires that to be setup.
    *   Like the `ShiroModule`, this module is used by extending it and adding your own custom configuration.

*   ShiroAopModule
    *   Uses [Guice AOP](https://github.com/google/guice/wiki/AOP) to implement the Shiro AOP annotations. This module is primarily concerned with adapting Shiro `AnnotationMethodInterceptors` to the Guice method interceptor model.
    *   This module is typically used by simply installing it. However, if you have your own `AnnotationMethodInterceptors` written for Shiro, they can be easily incorporated by extending it.

<a name="Guice-GettingStarted"></a>
Getting Started
---------------

The most simple configuration is to extend `ShiroModule` to install your own `Realm`.

``` java
class MyShiroModule extends ShiroModule {
    protected void configureShiro() {
        try {
            bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
        } catch (NoSuchMethodException e) {
            addError(e);
        }
    }

    @Provides
    Ini loadShiroIni() {
        return Ini.fromResourcePath("classpath:shiro.ini");
    }
}
```

In this case, user and role configuration would go in the `shiro.ini` file.

#warning('shiro.ini usage in Guice', 'It is important to note that, in this above configuration, only the `users` and `roles` sections from the ini file are used.')

Then, the module is used to create a Guice injector, and the injector is used to obtain a `SecurityManager`. The following example serves the same purpose as the first three lines in the [Quickstart](10-minute-tutorial.html#10MinuteTutorial-Quickstart.java) example.

``` java
Injector injector = Guice.createInjector(new MyShiroModule());
SecurityManager securityManager = injector.getInstance(SecurityManager.class);
SecurityUtils.setSecurityManager(securityManager);
```

<a name="Guice-AOP"></a>
AOP
---

Shiro includes several annotations and method interceptors useful for performing authorization via AOP. It also provides a simple API for writing Shiro-specific method interceptors. shiro-guice supports this with the `ShiroAopModule`.

To use it, simply instantiate and install the module alongside your application module and your `ShiroModule`.

``` java
Injector injector = Guice.createInjector(new MyShiroModule(), new ShiroAopModule(), new MyApplicationModule());
```

If you have written custom interceptors that conform to Shiro's api, you may find it useful to extend the `ShiroAopModule`.

``` java
class MyShiroAopModule extends ShiroAopModule {
    protected void configureInterceptors(AnnotationResolver resolver)
    {
        bindShiroInterceptor(new MyCustomAnnotationMethodInterceptor(resolver));
    }
}
```

<a name="Guice-Web"></a>
Web
---

shiro-guice's web integration is designed to integrate Shiro and its filter paradigm with Guice's servlet module. If you are using Shiro in a web environment, and using Guice's servlet module, then you should extend ShiroWebModule rather than ShiroModule. Your web.xml should be setup exactly as Guice's servlet module recommends.

``` java
class MyShiroWebModule extends ShiroWebModule {
    MyShiroWebModule(ServletContext sc) {
        super(sc);
    }

    protected void configureShiroWeb() {
        try {
            bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
        } catch (NoSuchMethodException e) {
            addError(e);
        }

        addFilterChain("/public/**", ANON);
        addFilterChain("/stuff/allowed/**", AUTHC_BASIC, config(PERMS, "yes"));
        addFilterChain("/stuff/forbidden/**", AUTHC_BASIC, config(PERMS, "no"));
        addFilterChain("/**", AUTHC_BASIC);
    }

    @Provides
    Ini loadShiroIni() {
        return Ini.fromResourcePath("classpath:shiro.ini");
    }
}
```

In the previous code, we have bound an `IniRealm` and setup four filter chains. These chains would be equivalent to the following ini configuration.

``` ini
[urls]
/public/** = anon
/stuff/allowed/** = authcBasic, perms["yes"]
/stuff/forbidden/** = authcBasic, perms["no"]
/** = authcBasic
```

In shiro-guice, the filter names are Guice keys. All of the default Shiro filters are available as constants, but you are not limited to those. In order to use a custom filter in a filter chain, you would do

``` java
Key customFilter = Key.get(MyCustomFilter.class);

addFilterChain("/custom/**", customFilter);
```

We still have to tell guice-servlets about our Shiro filter. Since the `ShiroWebModule` is private, and guice-servlets does not give us a way to expose a filter mapping, we have to bind it manually.

``` java
ShiroWebModule.guiceFilterModule()
```

Or, from within an application module,

``` java
ShiroWebModule.bindGuiceFilter(binder())
```

<a name="Guice-Properties"></a>
Properties
----------

A number of Shiro classes expose configuration parameters via setter methods. shiro-guice will inject these if it finds a binding for `@Named("shiro.{propName}")`. For instance, to set the session timeout, you could do the following.

``` java
bindConstant().annotatedWith(Names.named("shiro.globalSessionTimeout")).to(30000L);
```

If this paradigm doesn't work for you, you may also consider using a provider to instantiate the object and invoking the setters directly.

<a name="Guice-InjectionofShiroObjects"></a>
Injection of Shiro Objects
--------------------------

shiro-guice uses a Guice `TypeListener` to perform injection on native Shiro classes (any class in a subdirectory of `org.apache.shiro` but not `org.apache.shiro.guice`). However, Guice only considers explicitly bound types as candidates for `TypeListeners`, so if you have a Shiro object that you want injected, you have to declare it explicitly. For instance, to set the `CredentialsMatcher` for a realm, we would need to add the following bindings:

``` java
bind(CredentialsMatcher.class).to(HashedCredentialsMatcher.class);
bind(HashedCredentialsMatcher.class);
bindConstant().annotatedWith(Names.named("shiro.hashAlgorithmName")).to(Md5Hash.ALGORITHM_NAME);
```

#lendAHandDoc()

<input type="hidden" id="ghEditPage" value="guice.md.vtl"></input>
